// 高德地图
var AMap = require('AMap');
var _ = require('lodash');
// 字符串颜色转数字颜色
const Color = require('color-js');
class LwMap {
  /**
   * 全局对象：
   * this.map 真实的map对象
   * this.mapBox map中存放覆盖物的容器
   */

  /**
   * 构造方法
   * container: DOM ID
   * center: 中心点 eg: [116.404, 39.915] 北京
   * zoom: 缩放级别 {Number | Array(3)[zoom, minZoom, maxZoom]}
   */
  constructor (container, center = [116.404, 39.915], zoom = 13, extraConfig = {}) {
    var isNy = location.href.includes('bh.html');
    var getTileUrl = isNy ? 'http://2.20.101.180:32457/serviceaccess/service/ogcservice/wmts/wuxi_vector?service=WMTS&request=GetTile&version=1.0.0&layer=vec&style=default&tileMatrixSet=c&format=tiles&height=256&width=256&tilematrixSet=c&tk=56e2ef8967b3a0dbb746b7a40b7faa94&tilematrix=[z]&tilerow=[y]&&tilecol=[x]'
                          : 'http://t0.tianditu.gov.cn/DataServer?T=vec_w&tk=c27c613115979d179e2794dcb248c29d&x=[x]&y=[y]&l=[z]';
    var zooms = isNy ? [10, 18] : [6, 18];
    var options = {
      resizeEnable: true,
      rotateEnable: true,
      pitchEnable: true,
      buildingAnimation: true,
      expandZoomRange: true,
      center: center,
      layers: [
        new AMap.TileLayer({
          getTileUrl: getTileUrl,
          zooms: zooms
        })
      ],
      mapStyle: 'amap://styles/4c85d2670378fb87a0a9d28816cfa083' // 4fdb80e026ac9333276a536015019937
    };
    var zoomConfig;
    if (zoom instanceof Number) {
      zoomConfig = {
        zoom: zoom
      };
    } else if (zoom instanceof Array) {
      zoomConfig = {
        zoom: zoom[0],
        zooms: zooms
      };
    }
    options = _.extend(options, zoomConfig);
    if (extraConfig) {
      options = _.extend(options, extraConfig);
    }
    var map = new AMap.Map(container, options);
    var vm = this;
    vm.map = map;
    vm.mapBox = {}; // 所有地图元素的数组
    vm.loadPromise = new Promise((resolve) => {
      if (options.viewMode && options.viewMode == '3D') {
        map.plugin(['Map3D', 'ElasticMarker', 'AMap.MarkerClusterer'], function () {
          map.AmbientLight = new AMap.Lights.AmbientLight([1, 1, 1], 1);
          map.DirectionLight = new AMap.Lights.DirectionLight([1, 1, 1], [1, 1, 1], 1);
          var object3Dlayer = new AMap.Object3DLayer();
          map.add(object3Dlayer);
          vm.object3Dlayer = object3Dlayer;
          vm.obj3DBoundBox = []; // 所有图块的数组
          map.on('zoomend', function () {
            var zoom = vm.map.getZoom();
            vm.obj3DBoundBox.forEach(function (n) {
              if (n.zooms) {
                if (n.zooms[0] > zoom || n.zooms[1] < zoom) {
                  vm.object3Dlayer.remove(n);
                  if (n.linkObject) {
                    n.linkObject.forEach(o => {
                      if (o.type == 'prism') {
                        vm.object3Dlayer.remove(o);
                      } else {
                        vm.map.remove(o);
                      }
                    });
                  }
                } else {
                  if (vm.obj3DBoundBox.includes(n)) {
                    vm.object3Dlayer.add(n);
                    if (n.linkObject) {
                      n.linkObject.forEach(o => {
                        if (o.type == 'prism') {
                          vm.object3Dlayer.add(o);
                        } else {
                          vm.map.add(o);
                        }
                      });
                    }
                  }
                }
              }
            });
          });
          vm.add3DBoundListen();
          resolve();
        });
      } else {
        resolve();
      }
    });
  }

  // 需要实现的方法
  /**
   * 地图移动
   * 参数 二维坐标
   */
  panTo (point) {
    this.map.panTo(point);
  }

  addControlBar (offset = [0, 0], zoom = 1) {
    var vm = this;
    vm.map.plugin(['AMap.ControlBar'], function () {
      vm.map.addControl(new AMap.ControlBar({
        showZoomBar: false,
        showControlButton: true,
        position: { left: offset[0], top: offset[1], zoom: zoom }
      }));
    });
  }

  /**
   * 设置地图缩放级别
   * 参数 zoom
   */
  setZoom (zoom) {
    this.map.setZoom(zoom);
  }

  getZoom () {
    return this.map.getZoom();
  }

  /**
   * 设置地图缩放级别
   */
  setCenterAndZoom (point, zoom) {
    this.map.setZoomAndCenter(zoom, point);
  }

  /**
   * 增加标注物
   * 参数 id，url, 坐标点, 图片偏移，点击事件
   */
  addMarker (id, url, point, size, offset, onclick, params, labelName) {
    var markerContent = '' +
      `<div class="custom-content-marker">
      <img ${size ? `width="${size[0]}" height="${size[1]}"` : ''}  src="${url}">
    </div>`;
    var config = {
      position: new AMap.LngLat(point[0], point[1]),
      content: markerContent,
      offset: new AMap.Pixel(-offset[0], -offset[1]) // 以 icon 的 [center bottom] 为原点
    };
    labelName && (config = _.extend(config, {
      label: {
        content: `<div style="font-size: 12px;" color: '#e0d650'>${labelName}</div>`,
        offset: new AMap.Pixel(-5, 5),
        direction: 'bottom'
      }
    }));
    var marker = new AMap.Marker(config);
    marker = _.extend(marker, params);
    onclick && marker.on('click', onclick);
    this.__addObject(id, marker);
  }

  addBreatheMarker (id, url, point, size, offset, defaultShow, onclick, params, labelName) {
    var vm = this;
    var markerContent = '' +
      `<div class="custom-content-marker breathe-anm">
      <img ${size ? `width="${size[0]}" height="${size[1]}"` : ''}  src="${url}">
    </div>`;
    var config = {
      position: new AMap.LngLat(point[0], point[1]),
      content: markerContent,
      offset: new AMap.Pixel(-offset[0], -offset[1]) // 以 icon 的 [center bottom] 为原点
    };
    labelName && (config = _.extend(config, {
      label: {
        content: `<div style="font-size: 12px;" color: '#e0d650'>${labelName}</div>`,
        offset: new AMap.Pixel(-5, 5),
        direction: 'bottom'
      }
    }));
    var marker = new AMap.Marker(config);
    marker = _.extend(marker, params);
    marker.hide();
    vm.__addObject(id, marker);
    if (defaultShow) {
      setTimeout(() => {
        marker.show();
        vm.setAnimation(marker, 'DROP', 900);
        // // add3Dline && vm.add3DLine([120.343274, 31.777696], point);
        // vm.__addObject(id, marker);
        // vm.setAnimation(marker, 'BOUNCE', 900);
      }, Math.random() * 1500);
    }
    onclick && marker.on('click', onclick);
    // this.__addObject(id, marker);
  }

  // 增加海量点
  addMassMarker (id, data, url, size, offset, onclick) {
    if (!data.length) { return; }
    var style = [{
      url: url,
      size: new AMap.Size(size[0], size[1]),
      anchor: new AMap.Pixel(offset[0], offset[0])
    }];
    var objs = data.map((a) => {
      return {
        lnglat: a.position,
        id: a.id,
        name: a.id,
        style: 0
      };
    });

    // data.forEach((a) => {
    //   if (a.title) {
    //     var marker = new AMap.Marker({content: ''});
    //     marker.setPosition(a.position);
    //     marker.setLabel({content: `<div class="massmarker">${a.title}</div>`});
    //     marker.type = 'activity';
    //     this.__addObject(a.id + 'Marker', marker);
    //   }
    // });

    var mass = new AMap.MassMarks(objs, {
      opacity: 1,
      zIndex: 2000,
      zooms: [0, 20],
      cursor: 'pointer',
      style: style
    });
    onclick && mass.on('click', (e) => {
      this.stopPropagation = true;
      onclick(e);
      setTimeout(() => {
        this.stopPropagation = false;
      }, 200);
    });
    mass.type = 'activity';
    this.__addObject(id, mass);
  }

  // 增加宽线
  addMeshLine (feature, height, width = 4, color = 'rgba(55,129,240, 0.9)', zooms) {
    var path = [];
    feature.geometry.coordinates[0].forEach(function (i) {
      path.push(new AMap.LngLat(i[0], i[1]));
    });
    var meshLine = new AMap.Object3D.MeshLine({
      path: path,
      height: height,
      color: color,
      width: width
    });
    zooms && (meshLine.zooms = zooms);
    // this.obj3DBoundBox.push(meshLine);
    this.object3Dlayer.add(meshLine);
    return meshLine;
  }

  // 增加宽线
  addTextLabel (feature, height) {
    var text = new AMap.Text({
      text: feature.properties.name,
      verticalAlign: 'bottom',
      position: feature.properties.cp,
      height: height * 1.2,
      style: {
        'background-color': 'transparent',
        'text-align': 'center',
        'border': 'none',
        'color': 'white',
        'font-size': '16px'
        // ,
        // '-webkit-text-stroke': '0.5px #70ee70'
      }
    });
    this.__addObject(feature.id + '_text', text);
  }

  // 聚合点
  addMarkerCluster (id, data, url, size, offset, onclick) {
    if (!data.length) { return; }
    var vm = this;
    var markerContent = '' +
      `<div class="custom-content-marker">
      <img ${size ? `width="${size[0]}" height="${size[1]}"` : ''}  src="${url}">
    </div>`;
    vm.map.plugin(['AMap.MarkerClusterer'], function () {
      var markers = data.map((a) => {
        return new AMap.Marker({
          position: a.position,
          content: markerContent,
          offset: new AMap.Pixel(-offset[0], -offset[1])
        });
      });
      // eslint-disable-next-line
      new AMap.MarkerClusterer(vm.map, markers);
    });
  }

  // 移除物体 参数 name : 需要删除物体的ID
  removeObject (name) {
    var obj = this.mapBox[name];
    if (obj) {
      this.map.remove(obj);
    }
    delete this.mapBox[name];
  }

  //
  /**
   * 添加 3D 图块
   * 参数 id : 每一块图块; boundArray : 每一个图块的GPS坐标; color : 图块颜色;
   * opacity : 透明度; height : 图块高度; zooms :[显示区间]; onclick: 点击事件
   */
  add3DBoundary (id, boundArray, color = '#b5c817', opacity = 0.7, height = 2000, zooms = '', onclick = '') {
    var bounds = [];
    boundArray.forEach(function (i) {
      bounds.push(new AMap.LngLat(i[0], i[1]));
    });
    var colorObj = Color(color);
    var rgba = [colorObj.red, colorObj.green, colorObj.blue, opacity];
    // var rgb = [colorObj.red, colorObj.green, colorObj.blue, 1];
    var mesh = new AMap.Object3D.Prism({
      path: bounds,
      height: height,
      color: rgba
    });

    mesh.zooms = zooms;
    mesh.backOrFront = 'both';
    mesh.transparent = true;
    mesh.lwcolor = color;
    mesh.colorListen = true;
    this.obj3DBoundBox.push(mesh);
    this.object3Dlayer.add(mesh);
    this.__addObject(id, mesh);
    onclick && (mesh.lwClick = onclick);
  }

  add3DBoundaryByFeatureV2 (feature, rgb, opacity = 0.7, height = 2000, zooms = '', onclick = '', type = '') {
    var bounds = [];
    feature.geometry.coordinates[0].forEach(function (i) {
      bounds.push(new AMap.LngLat(i[0], i[1]));
    });
    var color = rgb || feature.properties.fillColor || this.__getRandomRgbColor();

    var colorObj = Color(color);
    var rgba = [colorObj.red, colorObj.green, colorObj.blue, opacity];
    var rgb1 = [0.42, 0.98, 1, 1]; // 底部边缘
    var rgb2 = [0.42, 0.98, 1, opacity]; // 顶部边缘
    var mesh = new AMap.Object3D.Mesh();
    var geometry = mesh.geometry;
    var verticesLength = bounds.length * 2;
    var path = [];
    for (let i = 0; i < bounds.length; i += 1) {
      var point = this.map.lngLatToGeodeticCoord(bounds[i]);
      var x = point.x;
      var y = point.y;
      path.push([x, y]);
      geometry.vertices.push(x, y, 0); // 底部顶点
      geometry.vertices.push(x, y, -height); // 顶部顶点

      geometry.vertexColors.push.apply(geometry.vertexColors, rgb1); // 底部颜色
      geometry.vertexColors.push.apply(geometry.vertexColors, rgb2); // 顶部颜色

      var bottomIndex = i * 2;
      var topIndex = bottomIndex + 1;
      var nextBottomIndex = (bottomIndex + 2) % verticesLength;
      var nextTopIndex = (bottomIndex + 3) % verticesLength;

      geometry.faces.push(bottomIndex, topIndex, nextTopIndex); // 侧面三角形1
      geometry.faces.push(bottomIndex, nextTopIndex, nextBottomIndex); // 侧面三角形2
    }

    // 构建顶面三角形,为了区分顶面点和侧面点使用不一样的颜色,所以需要独立的顶点
    for (let i = 0; i < bounds.length; i += 1) {
      geometry.vertices.push.apply(geometry.vertices, geometry.vertices.slice(i * 6 + 3, i * 6 + 6)); // 底部顶点
      geometry.vertexColors.push.apply(geometry.vertexColors, rgba);
    }

    var triangles = AMap.GeometryUtil.triangulateShape(path);
    var offset = bounds.length * 2;

    for (let v = 0; v < triangles.length; v += 3) {
      geometry.faces.push(triangles[v] + offset, triangles[v + 2] + offset, triangles[v + 1] + offset);
    }
    mesh.zooms = zooms;
    mesh.type = type || feature.type;
    mesh.backOrFront = 'both';
    mesh.transparent = true;
    mesh.lwcolor = [...geometry.vertexColors]; // 复制一份顶点颜色
    mesh.lwOpacity = opacity;

    var text = new AMap.Text({
      text: feature.properties.name.replace('网格', '<br>网格'),
      verticalAlign: 'bottom',
      position: feature.properties.cp,
      height: height * 1.2,
      style: {
        'background-color': 'transparent',
        '-webkit-text-stroke': 'red',
        '-webkit-text-stroke-width': '0.5px',
        'text-align': 'center',
        'border': 'none',
        'color': 'white',
        'font-size': '18px',
        'font-weight': 600
      }
    });

    var meshLine = this.addMeshLine(feature, height + 1, 2, 'rgba(0, 255, 255, 1)', zooms);
    this.__addObject(feature.id + '_text', text);
    mesh.linkObject = [text, meshLine];
    this.obj3DBoundBox.push(mesh);
    this.object3Dlayer.add(mesh);
    onclick && (mesh.lwClick = onclick);
  }

  __clientPointToVector (p) {
    var p1 = new AMap.Pixel(p[0], p[1]);
    var o1 = this.map.containerToLngLat(p1);
    return this.map.lngLatToGeodeticCoord([o1.lng, o1.lat]);
  }
  /**
   * 清除类型为type的所有网格
   */
  removeFeature (type) {
    var vm = this;
    vm.obj3DBoundBox.forEach(function (obj) {
      if (obj.type == type) {
        if (obj.linkObject) {
          obj.linkObject.forEach(o => {
            vm.object3Dlayer.remove(o);
            vm.map.remove(o);
          });
        }
        vm.object3Dlayer.remove(obj);
      }
    });
    _.remove(vm.obj3DBoundBox, (n) => { return n.type == type; });
  }

  /**
   * 添加图块监听方法 : 添加点击放大 , 鼠标悬停换色监听
   * 参数 color : 鼠标选中颜色; opacity : 鼠标悬停图块透明度
   */
  add3DBoundListen (color = '#FFF52F', opacity = 0.7) {
    var _map = this.map;
    var vm = this;
    var tooltipMarker = new AMap.Marker({content: ' ', map: this.map});
    this.map.on('mousemove', function (ev) {
      vm.obj3DBoundBox.forEach(function (prism) {
        if (prism.lwcolor) {
          var vertexColors = prism.geometry.vertexColors;
          var len = vertexColors.length;
          if (prism.lwcolor instanceof Array) {
            for (let i = 0; i < len; i++) {
              vertexColors.splice(i, 1, prism.lwcolor[i]);
            }
          } else {
            var initColor = prism.lwcolor;
            var colorObj = Color(initColor);
            for (let i = 0; i < len / 4; i++) {
              var r = colorObj.red;
              var g = colorObj.green;
              var b = colorObj.blue;
              var a = prism.lwOpacity || 0.7;
              // 不能重新赋值，只允许修改内容
              vertexColors.splice(i * 4, 4, r, g, b, a);
            }
          }
          prism.needUpdate = true;
          prism.reDraw();
        }
      });
      // 选中色块染黄
      var pixel = ev.pixel;
      var px = new AMap.Pixel(pixel.x, pixel.y);
      var obj = _map.getObject3DByContainerPos(px, [vm.object3Dlayer], false) || {};
      var prism = obj.object;
      if (prism && prism.lwClick) {
        var colorObj = Color(color);
        var vertexColors = prism.geometry.vertexColors;
        var len = vertexColors.length;
        for (var i = 0; i < len / 4; i++) {
          var r = colorObj.red;
          var g = colorObj.green;
          var b = colorObj.blue;
          var a = opacity;
          // 不能重新赋值，只允许修改内容
          vertexColors.splice(i * 4, 4, r, g, b, a);
        }
        prism.needUpdate = true;
        prism.reDraw();
      }
      if (prism && prism.tooltip) {
        if (ev.pixel != vm.lockPixel) {
          vm.lockPixel = ev.pixel;
          vm.showTooltipTimeout && clearTimeout(vm.showTooltipTimeout);
          tooltipMarker.setLabel({content: ''});
          vm.showTooltipTimeout = setTimeout(() => {
            tooltipMarker.setPosition(ev.lnglat);
            tooltipMarker.setLabel({content: `<div class="el-tooltip__popper is-dark">${prism.tooltip.replace('网格', '<br>网格')}</div>`});
          }, 500);
        }
      } else {
        vm.lockPixel = '';
        vm.showTooltipTimeout && clearTimeout(vm.showTooltipTimeout);
        tooltipMarker.setLabel({content: ''});
      }
    });
    this.map.on('click', function (ev) {
      if (vm.stopPropagation) {
        return;
      }
      var pixel = ev.pixel;
      var px = new AMap.Pixel(pixel.x, pixel.y);
      var obj = _map.getObject3DByContainerPos(px, [vm.object3Dlayer], false) || {};
      var prism = obj.object;
      prism && prism.lwClick && prism.lwClick(ev, prism);
    });
  }

  /**
   * 增加灵活点标记，参数参考 addMarkerAndPath
   */
  addElasticMarker (id, position, imgPath, imgSize, imgAncher, lableName = '', labelOffset = [-35, 0], labelPosition = 'BM', typeName = '', onclick = '') {
    var marker = this.__buildElasticMarker(position, imgPath, imgSize, imgAncher, lableName, labelOffset, labelPosition);
    typeName && (marker.type = typeName);
    onclick && marker.on('click', onclick);
    this.__addObject(id, marker);
  }

  /**
   * 设置轨迹路线
   * 轨迹数组 pathArr: [[a,b], [a,b]],
   * 图片路径 imgPath: url,
   * 图片大小 imgSize: [num,num],
   * 图片锚点 imgAncher: [num,num],
   * 图片标签名称 lableName: 'abc',
   * 图片标签偏移 labelOffset: [num,num],
   * 图片与锚点的位置 position: /BL、BM、BR、ML、MR、TL、TM、TR分别代表左下角、底部中央、右下角、左侧中央、右侧中央、左上角、顶部中央、右上角,
   * 轨迹线 lineColor: '#aaaa',
   * 轨迹线宽 lineWeight : num,
   * 点移动速度 speed : num,
   * return 点操控办法:start, pause, resume, stop, setSpeed, setPassLine
   */
  addMarkerAndPath (pathArr, imgPath, imgSize, imgAncher, lableName = '', labelOffset = [-35, 0], position = 'BM', lineColor = '#1104c7', lineWeight = 10, speed = 1000) {
    var marker = this.__buildElasticMarker(pathArr[0][0], imgPath, imgSize, imgAncher, lableName, labelOffset, position);
    marker.linkObject = [];
    var vm = this;
    pathArr.forEach((apath) => {
      var polyline = new AMap.Polyline({
        path: apath,
        showDir: true,
        strokeColor: lineColor, // 线颜色
        strokeWeight: lineWeight // 线宽
      });
      vm.map.add(polyline);
      marker.linkObject.push(polyline);
    });
    // 删掉老的
    this.removeMarkerAndPath();
    this.__addObject('pathAndMarker', marker);
    return {
      marker: marker,
      path: pathArr,
      map: this.map,
      status: 0, // 0 停止   1: 在跑  2: 暂停,
      speed: speed,
      afterMoveAlongEnd: function () {
        console.log('跑完第' + ++this.pathIndex + '段');
        var nextPath = this.path[this.pathIndex];
        if (nextPath) {
          this.run(this.speed, this.pathIndex);
        }
      },
      afterMoveTo: function () {
        this.run(this.speed);
      },
      init: function () {
        // 增加监听方法
        // this.marker.on('movealong', this.afterMoveAlongEnd, this);
        this.marker.on('moveend', this.afterMoveTo, this);
        this.marker.setPosition(this.path[0][0]);
        this.pointIndex = [0, 0];
      },
      run: function (v, reRun = false, startPoint = [0, 0]) {
        if (reRun) {
          this.pointIndex = startPoint;
          this.marker.setPosition(this.path[startPoint[0]][startPoint[1]]);
          this.run(v);
          return;
        }
        this.status = 1;
        this.speed = v || this.speed;
        var index0 = this.pointIndex[0];
        var index1 = this.pointIndex[1];
        var currentPoint = this.path[index0][index1]; // 当前点
        var nextPoint = this.path[index0][index1 + 1];
        var vm = this;
        if (nextPoint) {
          index1++;
        } else {
          nextPoint = this.path[index0 + 1] && this.path[index0 + 1][0];
          if (nextPoint) {
            index0++;
            index1 = 0;
            this.pointIndex = [index0, index1];
            setTimeout(function () {
              vm.marker.setPosition(vm.path[index0][index1]);
              vm.run(v);
            }, 200);
            return;
          } else {
            // 已经跑完了
            return;
          }
        }
        this.pointIndex = [index0, index1];
        var distance = Math.abs(currentPoint.lat - nextPoint.lat) + Math.abs(currentPoint.lng - nextPoint.lng);
        console.log(distance);
        if (distance < 0.00001) { // 两个点之间距离特别短的话，跳过
          this.run(v);
          return;
        }
        vm.marker.moveTo(nextPoint, v);
      },
      setSpeed: function (speed) {
        this.speed = speed;
      },
      /**
       * 设置点暂停
       */
      pause: function () {
        if (this.status == 2) { return; }
        this.status = 2;
        this.marker.stopMove();
      },
      changeStep: function (offset) {
        this.marker.stopMove();
        var status = this.status;
        if (this.pointIndex) {
          var index0 = this.pointIndex[0];
          var index1 = this.pointIndex[1] + offset;
          var len1 = this.path[index0].length;
          if (offset > 0) { // 快进
            if (index1 >= len1) {
              if (this.path[index0 + 1]) {
                index0 += 1;
                index1 = 0;
              } else {
                index1 = len1 - 1;
              }
            }
          } else { // 快退
            if (index1 < 0) {
              if (index0 - 1 >= 0) {
                index0 -= 1;
                index1 = this.path[index0].length + index1;
                index1 < 0 && (index1 = 0);
              } else {
                index0 = 0;
                index1 = 0;
              }
            }
          }
          status == 1 && this.run(this.speed, true, [index0, index1]);
          if (status == 2) {
            this.pointIndex = [index0, index1];
            this.marker.setPosition(this.path[[index0]][index1]);
          }
        }
      },
      /**
       * 设置点继续移动
       */
      resume: function () {
        if (this.status == 1) { return; }
        this.status = 1;
        var index0 = this.pointIndex[0];
        var index1 = this.pointIndex[1];
        this.run(this.speed, true, [index0, index1]);
      },
      /**
       * 设置点停止
       */
      stop: function () {
        if (this.status == 0) { return; }
        this.status = 0;
        this.marker.stopMove();
      },
      /**
       * 设置已经行驶的路线
       * 已行驶路线颜色 lineColor
       * 已行驶路线透明度 lineopacity
       * 已行驶路线线宽 lineWeight
       * 已行驶路线直线样式 lineStyle
       */
      setPassLine: function (lineColor = '#AF5', lineopacity = 1, lineWeight = 6, lineStyle = 'solid') {
        var passedPolyline = new AMap.Polyline({
          map: this.map,
          strokeColor: lineColor,
          strokeOpacity: lineopacity,
          strokeWeight: lineWeight,
          strokeStyle: lineStyle
        });
        this.marker.on('moving', function (e) {
          passedPolyline.setPath(e.passedPath);
        });
      }
    };
  }

  addMarkerAndPathV2 (pathArr, imgPath, imgSize, imgAncher, lableName = '', labelOffset = [-35, 0], position = 'BM', lineColor = '#1104c7', lineWeight = 10, speed = 1000) {
    var vm = this;
    var marker = this.__buildElasticMarker(pathArr[0], imgPath, imgSize, imgAncher, lableName, labelOffset, position);
    marker.linkObject = [];
    // 删掉老的
    this.removeMarkerAndPath();
    this.__addObject('pathAndMarker', marker);
    // 绘制轨迹
    var polyline = new AMap.Polyline({
      path: pathArr,
      showDir: true,
      strokeColor: lineColor, // 线颜色
      strokeWeight: lineWeight // 线宽
    });
    // vm.map.add(polyline);
    marker.linkObject.push(polyline);

    // 覆盖轨迹
    var passedPolyline = new AMap.Polyline({
      strokeColor: "#AF5",
      strokeWeight: lineWeight
    });
    vm.map.add(passedPolyline);
    marker.linkObject.push(passedPolyline);

    vm.map.setFitView([polyline], true);
    return {
      map: vm.map,
      marker,
      speed: speed,
      historyArr: [],
      pathArr,
      afterMove: function (foo) {
        var vm = this;
        vm.marker.on('movealong', () => {
          vm.historyArr = vm.historyArr.concat(vm.pathArr);
          foo();
        });
      },
      start: function (speed) {
        var vm = this;
        vm.speed = speed;
        vm.marker.on('moving', (e) => {
          var line = vm.historyArr.concat(e.passedPath);
          passedPolyline.setPath(line);
        });

        // var lastPoint = this.pathArr[this.pathArr.length - 1];
        // this.lastPoint = [lastPoint.lng, lastPoint.lat];
        marker.moveAlong(this.pathArr, speed);
      },
      addPath: function (arr) {
        this.pathArr = arr;
        this.marker.linkObject.push(polyline);
        setTimeout(() => {
          this.marker.moveAlong(this.pathArr, this.speed);
        }, 200);

        // this.marker.pauseMove();
        // arr.forEach((n) => {
        //   this.pathArr.push(n);
        // });
        // this.marker.resumeMove();
      }
    };
  }

  // 移除
  removeMarkerAndPath () {
    var oldMarker = this.mapBox.pathAndMarker;
    if (oldMarker) {
      oldMarker.stopMove();
      var linkObjs = oldMarker.linkObject;
      if (linkObjs) {
        var map = this.map;
        linkObjs.forEach((n) => {
          map.remove(n);
        });
        map.remove(oldMarker);
      }
    }
  }

  getRandomPoint (pathArr) {
    var lngArr = pathArr.map((n) => n[0]);
    var latArr = pathArr.map((n) => n[1]);
    var maxX = _.max(lngArr);
    var minX = _.min(lngArr);
    var maxY = _.max(latArr);
    var minY = _.min(latArr);
    let result = [];
    while (result.length != 50) {
      let lng = minX + (maxX - minX) * Math.random();
      let lat = minY + (maxY - minY) * Math.random();
      let isPointInRing = AMap.GeometryUtil.isPointInRing([lng, lat], pathArr);
      if (isPointInRing) {
        result.push([lng, lat]);
      }
    }
    return result;
  }

  /**
   * 清除类型为type的所有网格
   * 删除的3D物体
   */
  removeObjByTypename (type) {
    var vm = this;
    vm.obj3DBoundBox.forEach(function (obj) {
      if (obj.type == type) {
        if (obj.linkObject) {
          obj.linkObject.forEach(o => {
            vm.map.remove(o);
            vm.object3Dlayer.remove(o);
          });
        }
        vm.object3Dlayer.remove(obj);
      }
    });
    _.remove(vm.obj3DBoundBox, (n) => { return n.type == type; });
  }

  /**
   * 画柱状图
   * 位置[lng, lat], value, 高度， 半径， 颜色
   */
  drawHistogram (point, value, height, radius, color) {
    var center = this.map.lngLatToGeodeticCoord(point);
    var mesh = this.__addRegularPrism(center, 4, height || value, radius, color);
    var text = new AMap.Text({
      text: value,
      verticalAlign: 'bottom',
      position: point,
      height: height + 200,
      style: {
        'background-color': 'transparent',
        '-webkit-text-stroke': 'blue',
        '-webkit-text-stroke-width': '0.5px',
        'text-align': 'center',
        'border': 'none',
        'color': 'white',
        'font-size': '32px',
        'font-weight': 600
      }
    });
    mesh.linkObject = [text];
    this.map.add(text);
    mesh.type = 'Histogram';
    this.obj3DBoundBox.push(mesh);
    this.object3Dlayer.add(mesh);
  }
  /**
   * 清除地图图标
   */
  clearActivities (foo) {
    var vm = this;
    !foo && (foo = (n) => n.lwType == 'activity');
    if (foo instanceof Function) {
      var keys = Object.keys(vm.mapBox);
      keys.forEach((key) => {
        let obj = vm.mapBox[key];
        if (foo(obj)) {
          vm.removeObject(key);
        }
      });
    }
  }

  showInfoWindow (content, position, anchor = 'bottom-center') {
    var infoWindow = new AMap.InfoWindow({
      anchor,
      content,
      closeWhenClickMap: true
    });
    this.infoWindow = infoWindow;
    infoWindow.open(this.map, position);
  }

  showCustomInfoWindow (content, position, anchor = 'bottom-left yymtest') {
    var infoWindow = new AMap.InfoWindow({
      isCustom: true,
      showShadow: true,
      autoMove: true,
      closeWhenClickMap: true,
      content,
      anchor
    });
    this.infoWindow = infoWindow;
    infoWindow.open(this.map, position);
  }

  closeInfoWindow () {
    this.infoWindow && this.infoWindow.close();
  }

  // 增加动画效果 物体 动画名称 持续时间
  setAnimation (obj, name = 'DROP', time) {
    var vm = this;
    if (obj && obj.setAnimation) {
      obj.setAnimation('AMAP_ANIMATION_' + name);
      if (time) {
        setTimeout(function () {
          vm.removeAnimation(obj);
        }, time);
      }
    }
  }

  removeAnimation (obj) {
    obj.setAnimation('AMAP_ANIMATION_NONE');
  }

  setRotationAndPitch (rotation, pitch) {
    this.map.setRotation(rotation);
    this.map.setPitch(pitch);
  }

  getRotationAndPitch () {
    return {
      rotation: this.map.getRotation(),
      pitch: this.map.getPitch()
    };
  }

  __bd2decrypt = function (lng, lat) {
    var X_PI = Math.PI * 3000.0 / 180.0;
    var x = lng - 0.0065;
    var y = lat - 0.006;
    var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);
    var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);
    return new AMap.LngLat(z * Math.cos(theta), z * Math.sin(theta));
  };

  addPolygon (boundArray, strokeColor = '#00eeff', fillColor = '#71B3ff', fillOpacity = 0.5) {
    var vm = this;
    var outer = [
      new AMap.LngLat(-360, 90, true),
      new AMap.LngLat(-360, -90, true),
      new AMap.LngLat(360, -90, true),
      new AMap.LngLat(360, 90, true)
    ];
    var pathArray = [
      outer
    ];
    pathArray.push(boundArray.map((i) => {
      return vm.__bd2decrypt(i[0], i[1]);
    }));
    var polygon = new AMap.Polygon({
      pathL: pathArray,
      strokeColor,
      strokeWeight: 1,
      fillColor,
      fillOpacity
    });
    polygon.setPath(pathArray);
    this.map.add(polygon);
  }

  // 私有方法
  __addObject (id, marker) {
    var obj = this.mapBox[id];
    if (obj) {
      // 已经有了
      // var linkObjs = obj.linkObject;
      // if (linkObjs) {
      //   var map = this.map;
      //   linkObjs.forEach((n) => {
      //     map.remove(n);
      //   });
      // }
      this.map.remove(obj);
    }
    this.map.add(marker);
    this.mapBox[id] = marker;
  }
  __getRandomRgbColor () {
    return new Array(3).fill(255).map((o) => {
      return o * Math.random();
    });
  }
  __buildElasticMarker (position, imgPath, imgSize, imgAncher, lableName = '', labelOffset = [-35, 0], labelPosition = 'BM') {
    var zoomStyleMapping = {
      5: 0,
      6: 0,
      7: 0,
      8: 0,
      9: 0,
      10: 0,
      11: 0,
      12: 0,
      13: 0,
      14: 0,
      15: 0,
      16: 0,
      17: 0,
      18: 0,
      19: 0,
      20: 0
    };
    return new AMap.ElasticMarker({
      position: position,
      zooms: [3, 20],
      styles: [{
        icon: {
          img: imgPath,
          size: imgSize, // 可见区域的大小
          ancher: imgAncher, // 锚点
          fitZoom: 13, // 最合适的级别
          scaleFactor: 1.1, // 地图放大一级的缩放比例系数
          maxScale: 2, // 最大放大比例
          minScale: 1 // 最小放大比例
        },
        label: {
          content: lableName,
          offset: labelOffset,
          position: labelPosition
        }
      }],
      zoomStyleMapping: zoomStyleMapping,
      autoRotation: true,
      angle: -90
    });
  }

  // https://lbs.amap.com/api/javascript-api/example/mesh/mesh 画柱状图方法
  __addRegularPrism (center, segment, height, radius, color = '#00f') {
    var colorObj = Color(color);
    var topColor = [colorObj.red, colorObj.green, colorObj.blue, 0.9];
    var bottomColor = [colorObj.red, colorObj.green, colorObj.blue, 0.4];
    var cylinder = new AMap.Object3D.Mesh();
    var geometry = cylinder.geometry;
    var verticesLength = segment * 2;
    var path = [];
    for (let i = 0; i < segment; i += 1) {
      var angle = 2 * Math.PI * i / segment;
      var x = center.x + Math.cos(angle) * radius;
      var y = center.y + Math.sin(angle) * radius;
      path.push([x, y]);
      geometry.vertices.push(x, y, 0); // 底部顶点
      geometry.vertices.push(x, y, -height); // 顶部顶点

      geometry.vertexColors.push.apply(geometry.vertexColors, bottomColor); // 底部颜色
      geometry.vertexColors.push.apply(geometry.vertexColors, topColor); // 顶部颜色

      var bottomIndex = i * 2;
      var topIndex = bottomIndex + 1;
      var nextBottomIndex = (bottomIndex + 2) % verticesLength;
      var nextTopIndex = (bottomIndex + 3) % verticesLength;

      geometry.faces.push(bottomIndex, topIndex, nextTopIndex); // 侧面三角形1
      geometry.faces.push(bottomIndex, nextTopIndex, nextBottomIndex); // 侧面三角形2
    }

    // 构建顶面三角形,为了区分顶面点和侧面点使用不一样的颜色,所以需要独立的顶点
    for (let i = 0; i < segment; i += 1) {
      geometry.vertices.push.apply(geometry.vertices, geometry.vertices.slice(i * 6 + 3, i * 6 + 6)); // 底部顶点
      geometry.vertexColors.push.apply(geometry.vertexColors, topColor);
    }

    var triangles = AMap.GeometryUtil.triangulateShape(path);
    var offset = segment * 2;

    for (let v = 0; v < triangles.length; v += 3) {
      geometry.faces.push(triangles[v] + offset, triangles[v + 2] + offset, triangles[v + 1] + offset);
    }

    cylinder.transparent = true; // 如果使用了透明颜色，请设置true
    return cylinder;
  };
}
export default LwMap;
